from BaseViewTestCase import BaseViewTestCase
from skillchallenge.models import *
from skillchallenge.game import *

class NewCharViewTestCase(BaseViewTestCase):
    
    def test_index(self):
        "when i try to access the index i'm redirected to login"
        response = self.client.get('/')
        self.assertRedirects(response, '/accounts/login/?next=/', 302, 200)
        
    def test_index_character_creation(self):
        "when i try to access the index and there is no character i'm redirectioned to character creation."
        self.client.login(username="test", password="test")
        response = self.client.get('/')
        self.assertRedirects(response, '/character/', 302, 200)

    def test_index_character_exists(self):
        "when i try to access the index and there is character i'm redirectioned to the game."
        self.client.login(username="test", password="test")
        Character(name=self.name).save()
        response = self.client.get('/')
        self.assertRedirects(response, '/game/1', 302, 200)
    
    def test_character_template(self):
        "when i try to access the character creation the page show be newcharacter.html."
        response = self.client.get('/character/')
        self.assertTemplateUsed(response, 'skillchallenge/newcharacter.html')
    
    def test_character_post_skill(self):
        "when i try do save a skill the skill is saved and showed at the template"
        s = Skill()
        s.name = 'testskill'
        s.save()
        response = self.client.post('/character/', {'skillstotrain':s.id})
        self.assertTemplateUsed(response, 'skillchallenge/newcharacter.html')
        self.assertTrue(Skill.objects.get(id=1) in response.context[0]['skillset'])
    
    def test_character_post_two_skills(self):
        "when i try do save two skills the skills are saved and showed at the template"
        s = Skill()
        s.name = 'testskill1'
        s.save()
        response = self.client.post('/character/', {'skillstotrain':s.id})
        
        s = Skill()
        s.name = 'testskill2'
        s.save()
        response = self.client.post('/character/', {'skillstotrain':s.id})
        
        self.assertTrue(Skill.objects.get(id=1) in response.context[0]['skillset'])
        self.assertTrue(Skill.objects.get(id=2) in response.context[0]['skillset'])
        
    def test_character_post_maximum_skill(self):
        "when i try do save more than a maximum a message is showed"
        self.game.config.max_skills = 5
        self.game.config.save()
        
        for i in range(5):
            s = Skill()
            s.name = 'testskill' + str(i)
            s.save()
            response = self.client.post('/character/', {'skillstotrain':s.id})
        
        s = Skill()
        s.name = 'testskill6'
        s.save()
        response = self.client.post('/character/', {'skillstotrain':s.id})
        
        self.assertTrue(Skill.objects.get(id=6) not in response.context[0]['skillset'])
        self.assertTrue('there is a maximum of 5 skill per character' in response.context[0]['message'])
    
    def test_character_change_maximum_skills(self):
        "when i change the config the skill threshold should change"
        self.game.config.max_skills = 8
        self.game.config.save()
        
        for i in range(8):
            s = Skill()
            s.name = 'testskill' + str(i)
            s.save()
            response = self.client.post('/character/', {'skillstotrain':s.id})
        
        s = Skill()
        s.name = 'testskill9'
        s.save()
        response = self.client.post('/character/', {'skillstotrain':s.id})
        
        self.assertTrue(Skill.objects.get(id=9) not in response.context[0]['skillset'])
        self.assertTrue('there is a maximum of 8 skill per character' in response.context[0]['message'])
        
    def test_character_remove_skill_action(self):
        "the character page should have a button for remove skill"
        s = Skill()
        s.name = 'testskill'
        s.save()
        
        response = self.client.post('/character/', {'skillstotrain':s.id})
        response = self.client.post('/character/', {'removeskill':s.id})
        self.assertTrue(self.client.session['skillset'] == [])
        
    def test_can_save_character(self):
        "only after limit skills choosed can save character."
        response = self.client.get('/character/')
        self.assertTrue(response.context[0]['can_save'] == False)
        
        for i in range(3):
            s = Skill()
            s.name = 'testskill' + str(i)
            s.save()
            response = self.client.post('/character/', {'skillstotrain':s.id})
            
        response = self.client.get('/character/')
        self.assertTrue(response.context[0]['can_save'] == True)
        
    def test_save_character_without_location_or_name(self):
        "to save a character both name and location should be selected"
        
        response = self.client.post('/character/', {'name': None, 'location':1})
        self.assertTemplateUsed(response, 'skillchallenge/newcharacter.html')
        self.assertTrue('you need to choose a name to save a character.' in response.context[0]['message'])
        
        response = self.client.post('/character/', {'name': 1, 'location':None})
        self.assertTemplateUsed(response, 'skillchallenge/newcharacter.html')
        self.assertTrue('you need to choose a location to save a character.' in response.context[0]['message'])
        
        
    def test_save_character(self):
        "after saved the character is saved."
        for i in range(3):
            s = Skill()
            s.name = 'testskill' + str(i)
            s.save()
            response = self.client.post('/character/', {'skillstotrain':s.id})
        
        response = self.client.post('/character/', {'name': 1, 'location': 1})
        
        self.assertRedirects(response, '/game/1')
        
        c = Character.objects.filter(name__text='testchar')[0]
        
        self.assertTrue(len(c.skill_features.all()) == 3)
        self.assertTrue(c.skill_features.all()[0].name == 'testskill0')
        self.assertTrue(c.skill_features.all()[1].name == 'testskill1')
        self.assertTrue(c.skill_features.all()[2].name == 'testskill2')
    
    def test_skill_repeat(self):
        "i can not train the same skill twice"
        s = Skill()
        s.name = 'testskill1'
        s.save()
        response = self.client.post('/character/', {'skillstotrain':s.id})
        response = self.client.post('/character/', {'skillstotrain':s.id})
        
        self.assertTrue(self.client.session['skillset'] == [s])
        
    def test_save_character_go_to_location(self):
        "after saved the game should set to the location (event rised)."
        response = self.client.post('/character/', {'name': 1, 'location': 1})
        self.assertRedirects(response, '/game/1')
        
        e = self.game.event_engine.fired_by_info(
                    self.game.location_engine.INITIAL_MOVE)[0]
        self.assertTrue(e.info.endswith('1'))
        
        self.assertTrue(len(self.game.player_available()) == 0)